package io.gitee.xyuesheng.day09;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Factory {
    private static final int MAX = 5;
    List<Integer> products = new ArrayList<>();

    private Lock lock = new ReentrantLock();//重入锁

    private Condition notEmpty = lock.newCondition();//创建一个工厂非空的条件
    private Condition notFull = lock.newCondition();//创建一个工厂非满的条件

    //生产者往工厂放数据
//    public synchronized void put(Integer i){
    public void put(Integer i) {
        lock.lock();//从这个地方开始，锁定一段代码块，一次只能一个线程进来执行
        /**
         *ctrl+alt+t,选中中间的代码，try+finally
         * lock.unlock();//解锁   移入finally
         */
        try {
            if (products.size() >= 5) {
                try {
                    System.out.println("工厂数据达到上限。。。。。。。。。。。。");
                    //等待工厂不满这个条件成立
                    notFull.await();

                    //wait();//等待消费者取出数据，等待products不满这个条件
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            products.add(i);

            //notify();//通知消费者，工厂里面有数据了，可以继续取
            notEmpty.signal();

            System.out.println("*****生产者放入了一个产品：" + i);
        } finally {
            lock.unlock();//解锁
        }
    }

    //    public synchronized Integer get(){
    public Integer get() {
        lock.lock();
        try {
            if (products.isEmpty()) {
                try {
                    System.out.println("................工厂里面没有数据，需要等待");
                    //等待工厂不为空
                    notEmpty.await();

                    //wait();//让当前线程处于等待另一个线程唤醒它
                    //wait会释放锁，wait必须在同步方法或者同步代码块里面
                    //sleep不会释放锁
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            //被其他线程唤醒
            //被唤醒不需要判空
////        if(!products.isEmpty()){
            Integer i = products.remove(0);
            System.out.println("#消费者取出了一个产品：" + i);
            //notify();//通知生产者，继续放数据
            notFull.signal();//发出信号：不满这个条件成立了

////        try {
////            Thread.sleep(1000);
////        } catch (InterruptedException e) {
////            e.printStackTrace();
////        }

            return i;
////        }
////        return null;
        } finally {
            lock.unlock();
        }
    }

}
